<?php

declare(strict_types=1);

class Sysinfo
{
    public function __construct()
    {
    }

    /**
     * 读取文件解析到array
     * @param data 源数据 array
     * @param separate 分隔符号 char
     * @return reslut 目标数据 array
     */
    private function ParseValue($data, $separate)
    {
        $result = array();
        foreach ($data as $val) {
            $val = explode($separate, $val, 2);
            if (!empty($val) && !empty(trim($val[0]))) {
                $result[trim($val[0])] = trim($val[1]);
            }
        }
        return $result;
    }

    /**
     * 获取网卡信息
     * @return netstat 网卡设备信息
     */

    private function GetNetDevice()
    {
        $array = file('/proc/net/dev');

        //处理网卡数据
        $swap = explode('|', $array[0]);
        $types = array();
        for ($i = 1; $i < count($swap); $i++)
            array_push($types, trim($swap[$i]));

        $swap = explode('|', $array[1]);
        $typecolumn = array();
        for ($i = 0; $i < count($types); $i++) {
            $temp = explode(' ', $swap[$i + 1]);
            $vals = array();
            for ($j = 0; $j < count($temp); $j++) {
                $val = trim($temp[$j]);
                if (!empty($val))  array_push($vals, $val);
            }
            $typecolumn[$types[$i]] = $vals;
        }

        $netstat = array();
        for ($i = 2; $i < count($array); $i++) {
            $swap = explode(':', $array[$i], 2);
            preg_match_all('/[0-9]+/', $swap[1], $temp);

            $result = array();
            $idx = 0;
            for ($j = 0; $j < count($types); $j++) {
                $line = array();
                for ($k = 0; $k < count($typecolumn[$types[$j]]); $k++) {
                    $line[$typecolumn[$types[$j]][$k]] = $temp[0][$idx];
                    $idx++;
                }
                $result[$types[$j]] = $line;
            }
            $netstat[trim($swap[0])] = $result;
        }
        return $netstat;
    }

    /**
     * 获取指定设备的信息
     * @param device array 设备列表
     * @return info array 格式数据
     */
    public function GetDeviceInfo(array $device = array())
    {

        $info = array();
        if (empty($device)) return json_encode($info);

        foreach ($device as $var) {

            switch ($var) {
                case 'now':
                    $info['now'] = time();
                    break;

                case 'uptime':
                    $data = file_get_contents('/proc/uptime');
                    $swap = explode(".", $data);
                    if (empty($swap)) {
                        $info['uptime'] = 0;
                    } else {
                        $info['uptime'] = $swap[0];
                    }
                    break;

                case 'user':
                    $info['user'] = get_current_user();
                    break;

                case 'hostname':
                    $info['hostname'] = gethostname();
                    break;

                case 'ip':
                    $info['ip'] = $_SERVER['SERVER_ADDR'];
                    break;

                case 'port':
                    $info['port'] = $_SERVER['SERVER_PORT'];
                    break;

                case 'memory':
                    $array = file('/proc/meminfo');
                    $array = $this->ParseValue($array, ':');
                    $info['memory'] = $array;
                    break;

                case 'disk':
                    $array = file('/proc/mounts');
                    foreach ($array as $v) {
                        if ($v[0] == '/') {
                            $swap = explode(' ', $v);
                            $temp = array();
                            $temp['total'] = disk_total_space($swap[1]);
                            $temp['free'] = disk_free_space($swap[1]);
                            $info['disk'][$swap[1]] = $temp;
                        }
                    }
                    break;

                case 'cpu':
                    $array = file('/proc/cpuinfo');
                    $array = $this->ParseValue($array, ':');
                    $info['cpu'] = $array;
                    break;

                case 'stat':
                    $array = file('/proc/stat');
                    $array = $this->ParseValue($array, ' ');
                    $info['stat'] = $array;
                    break;

                case 'loadavg':
                    $array = file('/proc/loadavg');
                    $array = explode(' ', $array[0]);
                    $info['loadavg'] = $array;
                    break;

                case 'net':
                    $info['net'] = $this->GetNetDevice();
                    break;

                case 'temp':
                    for ($i = 0;; $i++) {
                        $name = '/sys/class/thermal/thermal_zone' . $i . '/temp';
                        if (!file_exists($name)) break;
                        $temp = file_get_contents($name);
                        $info['temp']['thermal_zone' . $i] = $temp;
                    }
                    break;

                case 'cpufreq':
                    for ($i = 0;; $i++) {
                        $name = '/sys/devices/system/cpu/cpu' . $i . '/cpufreq/scaling_cur_freq';
                        if (!file_exists($name)) break;
                        $temp = file_get_contents($name);
                        $info['cpufreq']['cpu' . $i] = $temp;
                    }
                    break;

                default:
                    break;
            }
        }

        return $info;
    }
}
